package com.test.A14;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.StaticMethodMatcherPointcut;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Method;

/**** 
 * 切点匹配 可以使用execution
 * 或者@annotation
 * 或者自定义类继承StaticMethodMatcherPointcut一个实现的方式 ，可以根据重写的方法的参数，方法和类来判断是否匹配 
 * @author Administrator
 *
 */
public class A14_1 {
    public static void main(String[] args) throws NoSuchMethodException {
                   test3();
    }
    
    
    /****
                        匹配注解     在多个位置的话  需要自己实现StaticMethodMatcherPointcut抽象类
                        使用的自定义StaticMethodMatcherPointcut的实现
        pt1.matches 方法可以判断表达式是否匹配 第一个是方法对象，第二个是类对象
     */
    public static void test3()  throws NoSuchMethodException{
      StaticMethodMatcherPointcut pt3 = new StaticMethodMatcherPointcut() {
          @Override
          public boolean matches(Method method, Class<?> targetClass) {
              // 检查方法上是否加了 Transactional 注解
              MergedAnnotations annotations = MergedAnnotations.from(method);
              if (annotations.isPresent(Transactional.class)) {
                  return true;
              }
              // 查看类上是否加了 Transactional 注解
              // annotations =   MergedAnnotations.from(targetClass);//from(element, SearchStrategy.DIRECT) 默认的是从本类上来查询  
               annotations = MergedAnnotations.from(targetClass, MergedAnnotations.SearchStrategy.TYPE_HIERARCHY);//TYPE_HIERARCHY是集成树上来判断   可以判断父接口等
              if (annotations.isPresent(Transactional.class)) {
                  return true;
              }
              return false;
          }
      };

      System.out.println(pt3.matches(T1.class.getMethod("foo"), T1.class));
      System.out.println(pt3.matches(T1.class.getMethod("bar"), T1.class));
      System.out.println(pt3.matches(T2.class.getMethod("foo"), T2.class));
      System.out.println(pt3.matches(T3.class.getMethod("foo"), T3.class));
 
    }
    
    
    /****
                      匹配注解    使用annotation
                      使用的AspectJExpressionPointcut切点
        pt1.matches 方法可以判断表达式是否匹配 第一个是方法对象，第二个是类对象
     */
    public static void test2()  throws NoSuchMethodException{
 
       AspectJExpressionPointcut pt2 = new AspectJExpressionPointcut();
       pt2.setExpression("@annotation(org.springframework.transaction.annotation.Transactional)");
       System.out.println(pt2.matches(T1.class.getMethod("foo"), T1.class));
       System.out.println(pt2.matches(T1.class.getMethod("bar"), T1.class));
  
 
    }
    
    /***
               匹配方法    使用execution
              使用的AspectJExpressionPointcut切点
     pt1.matches 方法可以判断表达式是否匹配 第一个是方法对象，第二个是类对象
     */
    public static void test1()  throws NoSuchMethodException{
       AspectJExpressionPointcut pt1 = new AspectJExpressionPointcut();
       pt1.setExpression("execution(* bar())");
       System.out.println(pt1.matches(T1.class.getMethod("foo"), T1.class));
       System.out.println(pt1.matches(T1.class.getMethod("bar"), T1.class));
    }


    static class T1 {
        @Transactional
        public void foo() {
        }
        public void bar() {
        }
    }

    @Transactional
    static class T2 {
        public void foo() {
        }
    }

    @Transactional
    interface I3 {
        void foo();
    }
    static class T3 implements I3 {
        public void foo() {
        }
    }
}